// pages/blectr/blectr.js\
var ble = require('../../utils/ble.js');
var debug = require('../../utils/debug.js');
var bleuuid = require('./bleuuid.js');

const BLECTR_MODUAL_NAME = "bleCtr";
const BLECTR_BLE_CON_TIMEOUT = 15000; // ble连接超时时间15s

const BLECTR_GET_SERSANDCHARS_STATUS_SUCCESS = 0; // 获取特征值成功
const BLECTR_GET_SERSANDCHARS_STATUS_ING = 1; // 正在获取
const BLECTR_GET_SERSANDCHARS_STATUS_INIT = 2; // 未获取

const BLECTR_CTR_FLAG_WRITE = 0; // 写
const BLECTR_CTR_FLAG_READ = 1; // 读操作

const BLECTR_RECIEVE_TEXT_MAX_LEN = 1000; // 接收显示区最长显示的字符个数为1000，超过后，最早接收到的字符将被删除

const BLECTR_SENDDATALIST_NUM = 12; // 发送区数据框个数

Page({
    /**
     * 页面的初始数据
     */
    data: {
        dialogViewShowFlag: false,
        bleCtrButtonObj: {
            loadingFlag: false,
            text: '断开'
        },
        sendCheckboxList: [{
            value: 0,
            checked: true,
            name: "16进制发送"
        }],
        /*
            sendDataList数组每个元素的属性：
            {
                checkBoxChecked: false,
                inputText:""
            }
        */
        sendDataList: [],
        
        recieveText: "",

        // 设备服务信息列表
        devInfo: [
            // {
            //     foldFlag: true, // 是否展开标志，true表示已经展开
            //     serviceName: "服务名称服务名称服务名称服务名称服务名称服务名称服务名称",  // 服务名称
            //     serviceUUID: "00002a54-0000-1000-8000-00805f9b34fb",  // 服务的uuid
            //     serviceChars: [    // 服务对应的特征值列表
            //         {
            //             charName: "特征值名称1", // 特征值名称
            //             charUUID: "00002a54-0000-1000-8000-00805f9b34fb", // 特征值UUID
            //             charWriteFlag: true, // 可写标志
            //             charReadFlag: true, // 可读标志
            //             charNotifyFlag: false, // 可通知标志
            //             charIndicateFlag: false // 也是可通知标志，不过是带应答的
            //         }
            //     ]
            // }
        ],

        cycleSendFlag: false, // 循环发送
        cycleSendInputText: "100",
    },

    userData: {
        hexRecFlag: true,   // 16进制接收
        hexSendFlag: true, // 16进制发送
        cycleTimersNumer: -1, // 循环发送定时器编号
        currDevId: "", // 设备ID
        getSersAndCharsStatus: BLECTR_GET_SERSANDCHARS_STATUS_INIT, // 表示当前获取服务ID和特征值ID状态

        currSelectCtrFlag: BLECTR_CTR_FLAG_WRITE, // 当前要选择读特征值，还是写特征值
        currWriteChar: {    // 当前选择的写入特征值
            flag: false, // 表示是否可用
            serId: "", // 服务ID
            charId: "" // 特征值ID
        },
        currReadChar: { // 当前选择的读/通知特征值
            flag: false, // 表示是否可用
            serId: "", // 服务ID
            charId: "" // 特征值ID
        },
    },

    bleCtrButtonClick: function(e) {
        if (ble.getDevConStaus(this.userData.currDevId) == ble.BLE_CON_SUCCESS 
            || ble.getDevConStaus(this.userData.currDevId) == ble.BLE_CON_ING) {
            this.disConDev();
        } else {
            this.conDev();
        }
    },

    sendCheckBoxClick: function(e) {
        this.userData.hexSendFlag = !this.userData.hexSendFlag;
    },

    serviceListItemClick: function(e) {
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "点击服务", e.currentTarget.id);
        this.data.devInfo[e.currentTarget.id].foldFlag = !this.data.devInfo[e.currentTarget.id].foldFlag;
        this.setData({['devInfo['+e.currentTarget.id+'].foldFlag']:this.data.devInfo[e.currentTarget.id].foldFlag});
    },

    charsListItemClick: function(e) {
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "点击特征值", e.currentTarget.id);
        // 解析出当前点击的特征值item在数组中的位置，逗号前面的是service对应的index，逗号后面的是chars中的index位置
        var index = e.currentTarget.id.split(',');
        var serIndex = parseInt(index[0], 10);
        var charIndex = parseInt(index[1], 10);

        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "点击的index", serIndex, charIndex);

        if (serIndex < this.data.devInfo.length && charIndex < this.data.devInfo[serIndex].serviceChars.length) {
            if (this.userData.currSelectCtrFlag == BLECTR_CTR_FLAG_READ) { // 读
                if (this.data.devInfo[serIndex].serviceChars[charIndex].charReadFlag
                    || this.data.devInfo[serIndex].serviceChars[charIndex].charNotifyFlag
                    || this.data.devInfo[serIndex].serviceChars[charIndex].charIndicateFlag) {

                    this.userData.currReadChar.flag = true;

                    // if (this.userData.currReadChar.serId != this.data.devInfo[serIndex].serviceUUID
                    //     || this.userData.currReadChar.charId != this.data.devInfo[serIndex].serviceChars[charIndex].charUUID) 
                        {
                            this.userData.currReadChar.serId = this.data.devInfo[serIndex].serviceUUID;
                            this.userData.currReadChar.charId = this.data.devInfo[serIndex].serviceChars[charIndex].charUUID;

                            var devID = this.userData.currDevId;
                            var serID = this.userData.currReadChar.serId;
                            var charID = this.userData.currReadChar.charId;

                            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "选择的读特征值ID", devID, serID, charID);

                            ble.enableDevCharNotify(
                                devID,
                                serID,
                                charID,
                                true
                            );
                        }

                    this.data.dialogViewShowFlag = false;
                    this.setData({['dialogViewShowFlag']: this.data.dialogViewShowFlag});
                } else {
                    wx.showToast({
                        title: '该特征值ID不可读/通知',
                        icon: 'none',
                        duration: 1500
                    });
                }
            } else { // 写
                if (this.data.devInfo[serIndex].serviceChars[charIndex].charWriteFlag) {
                    this.userData.currWriteChar.flag = true;
                    this.userData.currWriteChar.serId = this.data.devInfo[serIndex].serviceUUID;
                    this.userData.currWriteChar.charId = this.data.devInfo[serIndex].serviceChars[charIndex].charUUID;

                    this.data.dialogViewShowFlag = false;
                    this.setData({['dialogViewShowFlag']: this.data.dialogViewShowFlag});

                    debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "选择的写入特征值ID", this.userData.currDevId, this.userData.currWriteChar.serId, this.userData.currWriteChar.charId);
                } else {
                    wx.showToast({
                        title: '该特征值ID不可写',
                        icon: 'none',
                        duration: 1500
                    });
                }
            }
        }
    },

    // 选择服务ID和特征值id=0表示选择写入ID，id=1表示选择读取ID
    sendSelectSerIdButtonClick: function(e) {
        let status = ble.getDevConStaus(this.userData.currDevId);
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "选择ID", e.currentTarget.id, status);
        if (status != ble.BLE_CON_SUCCESS) {
            wx.showToast({
                title: '设备未连接',
                icon: 'none',
                duration: 1500
            });

            return;
        }

        if (e.currentTarget.id == "0") {
            this.userData.currSelectCtrFlag = BLECTR_CTR_FLAG_WRITE;
        } else {
            this.userData.currSelectCtrFlag = BLECTR_CTR_FLAG_READ;
        }

        this.getDevServicesAndChars(true);
    },

    // getDevCharsCallback: function(charsArr) {
        
    // },

    /**
     * 获取设备的服务列表和特征值列表
     * @param {boolean} flag 表示是否弹出服务和特征值列表框，有些时候需要做后台搜索
     */
    getDevServicesAndChars: function(flag) {
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "开始获取设备服务ID", this.userData.currDevId);

        if (flag) {
            this.data.dialogViewShowFlag = true;
            this.setData({['dialogViewShowFlag']: this.data.dialogViewShowFlag});
        }

        if (this.userData.getSersAndCharsStatus == BLECTR_GET_SERSANDCHARS_STATUS_SUCCESS
            || this.userData.getSersAndCharsStatus == BLECTR_GET_SERSANDCHARS_STATUS_ING) {
            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "获取设备服务ID成功或者已经在获取了", this.userData.currDevId);
            return;
        }

        this.data.devInfo.length = 0;   // 清空设备信息数组
        this.userData.getSersAndCharsStatus = BLECTR_GET_SERSANDCHARS_STATUS_ING;

        ble.getDevServices(this.userData.currDevId,
            (serArr) => {
                if (serArr != null) {
                    debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_ERROR, "设备服务ID获取成功", this.userData.currDevId, serArr);
                    for (let i = 0; i < serArr.services.length; i++) {
                        // services[i]包含了两个关键属性：isPrimary，uuid
                        let uuidName = bleuuid.getUuidName(serArr.services[i].uuid);
                        this.data.devInfo.push(
                            {
                                foldFlag: false, // 是否展开标志，true表示已经展开
                                serviceName: uuidName,  // 服务名称
                                serviceUUID: serArr.services[i].uuid,  // 服务的uuid
                                serviceChars: []    // 服务对应的特征值列表                                   
                            }
                        );
                    }
                    this.setData({["devInfo"]: this.data.devInfo});

                    // 获取对应服务的特征值列表
                    for (let i = 0; i < serArr.services.length; i++) {
                        ble.getDevChars(
                            this.userData.currDevId,
                            serArr.services[i].uuid,
                            (chars) => {
                                /* 
                                    chars关键属性
                                    {
                                        deviceId,  // 安卓没有这个属性
                                        serviceId,  // 安卓没有这个属性
                                        characteristics[
                                            {
                                                uuid:
                                                properties: {
                                                    notify:
                                                    read:
                                                    write:
                                                    indicate:
                                                }
                                            },
                                        ]
                                    }
                                */
                            //    if (chars.deviceId != this.userData.currDevId) {
                            //        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "返回的特征值信息对应的设备ID异常");
                            //        return;
                            //    }

                                for (let k=0; k<this.data.devInfo.length; k++) {
                                    // if (this.data.devInfo[i].serviceUUID == chars.serviceId) {
                                    if (this.data.devInfo[k].serviceUUID == serArr.services[i].uuid) {
                                        // 添加特征值列表到对应的数据段
                                        for (let j=0; j<chars.characteristics.length; j++) {
                                            let charName = bleuuid.getUuidName(chars.characteristics[j].uuid);
                                            this.data.devInfo[k].serviceChars.push({
                                                charName: charName, // 特征值名称
                                                charUUID: chars.characteristics[j].uuid, // 特征值UUID
                                                charWriteFlag: chars.characteristics[j].properties.write, // 可写标志
                                                charReadFlag: chars.characteristics[j].properties.read, // 可读标志
                                                charNotifyFlag: chars.characteristics[j].properties.notify, // 可通知标志
                                                charIndicateFlag: chars.characteristics[j].properties.indicate // 可通知标志，带应答
                                            });
                                            
                                            // 如果是断开重连，并且notify有效，需要重新使能notify
                                            if (this.userData.currReadChar.flag && this.data.devInfo[k].serviceUUID == this.userData.currReadChar.serId && chars.characteristics[j].uuid == this.userData.currReadChar.charId) {
                                                var devID = this.userData.currDevId;
                                                var serID = this.userData.currReadChar.serId;
                                                var charID = this.userData.currReadChar.charId;
                    
                                                debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "重连重新使能notify功能", devID, serID, charID);
                    
                                                ble.enableDevCharNotify(
                                                    devID,
                                                    serID,
                                                    charID,
                                                    true
                                                );
                                            }
                                        }
                                        this.setData({['devInfo['+i+'].serviceChars']: this.data.devInfo[k].serviceChars});
                                        break;
                                    }
                                }
                            }
                        );
                    }
                } else {
                    debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_ERROR, "设备服务ID获取失败", this.userData.currDevId);
                    this.userData.getSersAndCharsStatus = BLECTR_GET_SERSANDCHARS_STATUS_INIT;
                }
            }
        );
    },

    conDev: function() {
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "开始连接设备", this.userData.currDevId);

        this.data.bleCtrButtonObj.loadingFlag = true;
        this.data.bleCtrButtonObj.text = "连接中";
        this.setData({["bleCtrButtonObj"]: this.data.bleCtrButtonObj});

        ble.connect(this.userData.currDevId, BLECTR_BLE_CON_TIMEOUT, 
            (deviceId, status) => {
                if (deviceId != this.userData.currDevId) {
                    return;
                }

                if (status == ble.BLE_CON_ING) {
                    // this.data.bleCtrButtonObj.loadingFlag = true;
                    // this.data.bleCtrButtonObj.text = "连接中";
                    // this.setData({["bleCtrButtonObj"]: this.data.bleCtrButtonObj});
                } else if (status == ble.BLE_CON_SUCCESS) {
                    this.data.bleCtrButtonObj.loadingFlag = false;
                    this.data.bleCtrButtonObj.text = "断开";
                    this.setData({["bleCtrButtonObj"]: this.data.bleCtrButtonObj});

                    // 每次连接成功后，就去重新搜索一次服务列表和特征值列表，因为微信小程序BLE设备在断开后，底层会清除以前搜索到的服务列表和特征值列表
                    this.userData.getSersAndCharsStatus = BLECTR_GET_SERSANDCHARS_STATUS_INIT;
                    this.getDevServicesAndChars(false);
                } else {
                    this.data.bleCtrButtonObj.loadingFlag = false;
                    this.data.bleCtrButtonObj.text = "未连接";
                    this.setData({["bleCtrButtonObj"]: this.data.bleCtrButtonObj});
                }
            }
        )
    },

    disConDev: function() {
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "断开设备", this.userData.currDevId);

        ble.disconnect(this.userData.currDevId, 
            (res) => {
                if (res) {
                    this.data.bleCtrButtonObj.loadingFlag = false;
                    this.data.bleCtrButtonObj.text = "未连接";
                    this.setData({["bleCtrButtonObj"]: this.data.bleCtrButtonObj});
                }
            }
        );
    },

    dialogViewTouchMove: function(e) {
        
    },

    dialogMashViewClick: function(e) {
        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "dialogMashViewClick");
        // 点击内容层之外区域（遮罩层），隐藏弹出窗口
        this.data.dialogViewShowFlag = false;
        this.setData({['dialogViewShowFlag']: this.data.dialogViewShowFlag});
    },

    sendDataListCheckBoxClick: function(e) {
        var index = parseInt(e.currentTarget.id, 10);
        if (index < this.data.sendDataList.length) {
            this.data.sendDataList[index].checkBoxChecked = !this.data.sendDataList[index].checkBoxChecked;
            this.setData({['sendDataList['+index+'].checkBoxChecked']: this.data.sendDataList[index].checkBoxChecked});
        }
    },

    // 注意： 不是每输入一个字符就调用一次，可能是输入了一串字符
    sendDataListInputEvent: function(e) {
        // console.log(e);
        var index = parseInt(e.currentTarget.id, 10);
        if (index < this.data.sendDataList.length) {
            this.data.sendDataList[index].inputText = e.detail.value;
        }
        // console.log(this.data.sendDataList[index].inputText);
        /*
        // 对输入数据做判断
        var value = e.detail.value; 
        var pos = e.detail.cursor;
        // console.log(this.data.sendDataList[index].inputText);
        if (pos > 0) {
            // console.log(value.length);
            if (this.userData.hexInputFlag) {   // 16进制输入方式
                for (let i=0; i<value.length; i++) {
                    var unicode = value.charCodeAt(i);
                    if (unicode < 48 || (unicode > 57 && unicode < 65) || (unicode > 70 && unicode < 97) || unicode > 102) { // 非16进制数据
                        wx.showToast({
                            title: '请输入16进制数据',
                            icon: 'none',
                            duration: 1500
                        });

                        return {
                            value: value.slice(0, i), //直接从非16进制数据的位置截取
                            cursor: i
                        }
                    }
                }
            }
        }
        */
    },

    /**
     *  按16进制方式转换字符串，并返回转换后的数据（ArrayBuffer）
     * @param {string} data 
     */
    transformSendDataByHex: function(data) {
        var text = data;
        var writeValueTmp = new ArrayBuffer(300); // input框最大输入140个字符，每个字符unicode占两个字节
        var writeValueUint8 = new Uint8Array(writeValueTmp);
        var writeValueLen = 0;

        let num = 0;
        let numIndex = 0;

        for (let i=0; i<text.length; i++) {
            if ((text[i]>='0' && text[i]<='9') || (text[i]>='a' && text[i]<='f') || (text[i]>='A' && text[i]<='F')) {
                if (numIndex == 0) {
                    num = text[i];
                    numIndex = 1;
                } else {
                    num += text[i];
                    numIndex = 0;
                    writeValueUint8[writeValueLen] = parseInt(num, 16);
                    writeValueLen++;
                    // debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据：", num);
                }
            } else {
                break;
            }
        }

        var writeValue = writeValueTmp.slice(0, writeValueLen);

        return writeValue;
    },

    /**
     *  按字符方式转换字符串，并返回转换后的数据（ArrayBuffer）
     * @param {string} data 
     */
    transformSendDataByChar: function(data) {
        var text = data;
        var writeValueTmp = new ArrayBuffer(300); // input框最大输入140个字符，每个字符unicode占两个字节
        var writeValueUint8 = new Uint8Array(writeValueTmp);
        var writeValueLen = 0;
    
        for (let i=0; i<text.length; i++) {
            let code = text.charCodeAt(i); // 转换为unicode码
            if (code > 255) {
                writeValueUint8[writeValueLen] = code / 255;
                writeValueLen++;
                writeValueUint8[writeValueLen] = code % 255;
                writeValueLen++;
            } else {
                writeValueUint8[writeValueLen] = code;
                writeValueLen++;
            }
        }

        var writeValue = writeValueTmp.slice(0, writeValueLen);

        return writeValue;
    },

    sendDataListButtonClick: function(e) {
        if (ble.getDevConStaus(this.userData.currDevId) != ble.BLE_CON_SUCCESS) {
            wx.showToast({
                title: '设备未连接',
                icon: 'none',
                duration: 1500
            });
            return;
        }

        if (!this.userData.currWriteChar.flag) {
            wx.showToast({
                title: '请先选择要写入的ID',
                icon: 'none',
                duration: 1500
            });
            return;
        }

        var index = parseInt(e.currentTarget.id, 10);
        if (index < this.data.sendDataList.length) {
            if (this.data.sendDataList[index].inputText.length != 0){
                var writeValue = "";
                // 16进制方式发送，每两个字符组成一个数据，如果遇到非16进制字符，数据转换将中止
                if (this.userData.hexSendFlag) { 
                    writeValue = this.transformSendDataByHex(this.data.sendDataList[index].inputText);
                } else {  // 字符方式发送
                    writeValue = this.transformSendDataByChar(this.data.sendDataList[index].inputText);
                }
                
                ble.writeDevCharValue(
                    this.userData.currDevId,
                    this.userData.currWriteChar.serId,
                    this.userData.currWriteChar.charId,
                    writeValue,
                    (res, errCode)=> {
                        if (res) {
                            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据发送成功", errCode);
                            wx.showToast({
                                title: '发送成功',
                                icon: 'none',
                                duration: 1500
                            });
                        } else {
                            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据发送失败", errCode);
                            wx.showToast({
                                title: '发送失败',
                                icon: 'none',
                                duration: 1500
                            });
                        }
                    }
                );
            } else {
                wx.showToast({
                    title: '请输入发送内容',
                    icon: 'none',
                    duration: 1500
                })
            }
        }
    },

    recieveHexShowCheckboxClick: function(e) {
        this.userData.hexRecFlag = !this.userData.hexRecFlag;
    },

    // 清空接收数据显示区
    recieveClearButtonClick: function(e) {
        this.data.recieveText = "";
        this.setData({['recieveText']: this.data.recieveText});
    },

    // 读一次对应的特征值ID
    recieveReadButtonClick: function(e) {
        let status = ble.getDevConStaus(this.userData.currDevId);
        if (status != ble.BLE_CON_SUCCESS) {
            wx.showToast({
                title: '设备未连接',
                icon: 'none',
                duration: 1500
            });

            return;
        }

        if (this.userData.currReadChar.flag) {
            var devID = this.userData.currDevId;
            var serID = this.userData.currReadChar.serId;
            var charID = this.userData.currReadChar.charId;

            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "读取特征值", devID, serID, charID);

            ble.readDevCharValue(
                devID,
                serID,
                charID,
                (res, errCode)=> {
                    if (res) {
                        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "读取特征值成功", errCode);
                    } else {
                        debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "读取特征值失败", errCode);
                    }
                }
            );             
        } else {
            wx.showToast({
                title: '请先选择要读取的ID',
                icon: 'none',
                duration: 1500
            });
        }
    },

    cycleSendCheckBoxClick: function(e) {
        if (!this.data.cycleSendFlag) {  // 开启循环发送
            let status = ble.getDevConStaus(this.userData.currDevId);
            if (status != ble.BLE_CON_SUCCESS) {
                wx.showToast({
                    title: '设备未连接',
                    icon: 'none',
                    duration: 1500
                });
                this.setData({['cycleSendFlag']:this.data.cycleSendFlag});
                return;
            }

            if (!this.userData.currWriteChar.flag) {
                wx.showToast({
                    title: '请先选择要写入的ID',
                    icon: 'none',
                    duration: 1500
                });
                this.setData({['cycleSendFlag']:this.data.cycleSendFlag});
                return;
            }

            let cycleTime = parseInt(this.data.cycleSendInputText);
            if (isNaN(cycleTime) || cycleTime <= 0) {
                wx.showToast({
                    title: '请输入正确的循环发送时间(1~99999)',
                    icon: 'none',
                    duration: 1500
                });
                this.setData({['cycleSendFlag']:this.data.cycleSendFlag});
                return;
            }

            this.data.cycleSendFlag = true;
            this.setData({['cycleSendFlag']:this.data.cycleSendFlag});

            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "开始循环发送", cycleTime);

            wx.showToast({
                title: '开始循环发送数据',
                icon: 'none',
                duration: 1500
            });

            this.userData.cycleTimersNumer = setInterval(
                (res)=>{
                    debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "循环发送一次数据");
                    for (let i=0; i<this.data.sendDataList.length; i++) {
                        if (this.data.sendDataList[i].checkBoxChecked && this.data.sendDataList[i].inputText.length > 0) {
                            var writeValue = "";
                            // 16进制方式发送，每两个字符组成一个数据，如果遇到非16进制字符，数据转换将中止
                            if (this.userData.hexSendFlag) { 
                                writeValue = this.transformSendDataByHex(this.data.sendDataList[i].inputText);
                            } else {  // 字符方式发送
                                writeValue = this.transformSendDataByChar(this.data.sendDataList[i].inputText);
                            }
                            
                            ble.writeDevCharValue(
                                this.userData.currDevId,
                                this.userData.currWriteChar.serId,
                                this.userData.currWriteChar.charId,
                                writeValue,
                                (res, errCode)=> {  // 循环发送不做数据发送成功和失败的判断
                                    // if (res) {
                                    //     debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据发送成功", errCode);
                                    // } else {
                                    //     debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据发送失败", errCode);
                                    // }
                                }
                            );
                        }
                    }
                },
                cycleTime,
                0,
            );
        } else { // 终止循环发送
            this.data.cycleSendFlag = false;
            this.setData({['cycleSendFlag']:this.data.cycleSendFlag}); // 需要setData，否则输入框的disable状态不会改变

            clearInterval(this.userData.cycleTimersNumer);
            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "停止循环发送数据");
            wx.showToast({
                title: '停止循环发送数据',
                icon: 'none',
                duration: 1500
            });
        }
    },

    cycleSendInputEvent: function(e) {
        // 对输入数据做判断
        var value = e.detail.value; 
        var pos = e.detail.cursor;
        if (pos > 0) {
            for (let i=0; i<value.length; i++) {
                // 限制输入数据类型和长度
                if (value[i] < '0' || value[i] > '9' || i>4) {
                    wx.showToast({
                        title: '请输入10进制数据(1~99999)',
                        icon: 'none',
                        duration: 1500
                    });

                    this.data.cycleSendInputText = value.slice(0, i); //直接从非数字进制数据的位置截取
                
                    return {
                        value: this.data.cycleSendInputText, 
                        cursor: i
                    }
                }
            }

            this.data.cycleSendInputText = value;
        } else {
            this.data.cycleSendInputText = "";
        }
    },

    // dialogContentButtonClick: function(e) {
    //     debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "dialogContentButtonClick");
    // },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
        debug.Debug(BLECTR_MODUAL_NAME,debug.DEBUG_DEBUG,"page onLoad", options);
        
        this.userData.currDevId = options.devId;
        // 根据devId去连接设备
        this.conDev();

        // 设置特征值回调
        ble.onDevCharValueChange((res) => {
            // res.value是一个ArrayBuffer
            var buffer = new Uint8Array(res.value);
            var currText = "";
            if (this.userData.hexRecFlag) {
                for (var i=0; i<buffer.length; i++) {
                    if (buffer[i] < 16) { // 如果该变量小于16,在前面补0
                        currText += '0';
                    }
                    currText += buffer[i].toString(16) + " "; // 转换为16进制的字符串
                }
            } else {
                //字符转unicode码：用charCodeAt();
                //unicode码转字符：用fromCharCode();
                for (var i=0; i<buffer.length; i++) {
                    if (buffer[i] >= 32 && buffer[i] <= 126) { // 有效的显示字符
                        currText += String.fromCharCode(buffer[i])+ " "; // 转换为unicode字符
                    } else { // 无效的显示字符
                        currText += "?" + " "; // 转换为ascii字符
                    }
                }
            }

            // 最长接收显示指定个字符，再长最先接收到在的字符就会被删除
            var subText = "";
            if (this.data.recieveText.length + currText.length > BLECTR_RECIEVE_TEXT_MAX_LEN) {
                subText = this.data.recieveText.slice(this.data.recieveText.length + currText.length - BLECTR_RECIEVE_TEXT_MAX_LEN, this.data.recieveText.length);       
                
                this.data.recieveText = subText + currText;
            } else {
                this.data.recieveText += currText;
            }
    
            this.setData({['recieveText']: this.data.recieveText});
        });

        // 获取本地存储的sendDataList
        var data = wx.getStorageSync('setDataList', false);
        if (data.length == BLECTR_SENDDATALIST_NUM 
            && typeof data[0].checkBoxChecked == 'boolean'
            && typeof data[11].checkBoxChecked == 'boolean') { // 大致校验一下数据是否正确
            this.data.sendDataList = data;
            this.setData({['sendDataList']: this.data.sendDataList});
        } else { // 生成默认的数据
            for (let i=0; i<BLECTR_SENDDATALIST_NUM; i++) {
                this.data.sendDataList.push(
                    {
                        checkBoxChecked: false,
                        inputText: ""
                    }
                );
            }
            this.setData({['sendDataList']: this.data.sendDataList});
        }
    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: function () {
        
    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function () {
        debug.Debug(BLECTR_MODUAL_NAME,debug.DEBUG_DEBUG,"page onShow");
    },

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide: function () {
        debug.Debug(BLECTR_MODUAL_NAME,debug.DEBUG_DEBUG,"page onHide");
    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function () {
        debug.Debug(BLECTR_MODUAL_NAME,debug.DEBUG_DEBUG,"page onUnload");
        // 清除获取状态
        this.userData.getSersAndCharsStatus = BLECTR_GET_SERSANDCHARS_STATUS_INIT;

        // 关闭特征值监听
        ble.offDevCharValueChange(()=> {
            debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "关闭特征值监听");
        });

        // 如果当前设备处于连接状态，退出该页面的时候，要去处理
        // 断开连接
        var status = ble.getDevConStaus(this.userData.currDevId);
        if (status == ble.BLE_CON_SUCCESS || status == ble.BLE_CON_ING) {
            ble.disconnect(this.userData.currDevId);
        }

        // sendDataList本地化存储，不加密
        wx.setStorageSync('setDataList', this.data.sendDataList, false);
    },

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function () {

    },

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: function () {

    },

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage: function () {

    }
})